package com.tbit.main.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.tbit.main.constant.*;
import com.tbit.main.h2.pojo.ParkPoint;
import com.tbit.main.pojo.*;
import com.tbit.main.service.*;
import com.tbit.main.util.DateTimeUtil;
import com.tbit.main.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static com.tbit.main.constant.RedisConstant.PHOTO;

@Slf4j
@Service("queueListenter")
public class QueueListenter {
    @Autowired
    private TerControlService terControlService;
    @Autowired
    private OrderLogService orderLogService;
    @Autowired
    private MachineOccupyService machineOccupyService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RuleRidePhotoLogService ruleRidePhotoLogService;
    @Autowired
    private DataService dataService;
    @Autowired
    private RideLogService rideLogService;
    @Autowired
    private ParkService parkService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private ParkPointService parkPointService;
    @Autowired
    private MachineStatusService machineStatusService;
    @Autowired
    private MachineAbnormalService machineAbnormalService;
    @Autowired
    private MachineBorrowService machineBorrowService;
    @Autowired
    private MannedService mannedService;

    @RabbitListener(queues = {"${mq.queue.tbitUqbikeWebMain}"}, concurrency = "5")
    @RabbitHandler
    public void onMessage(Message msg) {
        try {
            String respMsg = new String(msg.getBody(), "UTF-8");
            /**判断消息类型*/
            JSONObject object = JSON.parseObject(respMsg);
            int msgId = object.getIntValue("msgId");

            //log.info("指令结果："+object);

            String newTime = DateTimeUtil.getNowTime();

            switch (msgId) {
                case GatewayProtocol.MQ_MSG_ID_CONTROL_DOWN_RSP:
                    /*发送结果回复*/
                    break;
                case GatewayProtocol.MQ_MSG_ID_CONTROL_TER_RSP:
                    /*终端回复*/
                    String serNO = object.getJSONObject("data").getString("serNO");
                    String controlRet = object.getJSONObject("data").getString("controlRet");
                    String paramRet = object.getJSONObject("data").getString("paramRet");

                    String nowTime = DateTimeUtil.getNowTime();

                    String machineNOPhone = redisService.get(PHOTO + serNO);
                    if (machineNOPhone != null) {
                        String picList = object.getJSONObject("data").getJSONArray("picList").get(0).toString();
                        log.info("picList==={}", picList);
                        redisService.add(PHOTO + serNO, picList, 60);
                        RuleRidePhotoLog ruleRidePhotoLog = new RuleRidePhotoLog();
                        ruleRidePhotoLog.setFtpUrl(picList);
                        ruleRidePhotoLog.setMachineNO(machineNOPhone);
                        ruleRidePhotoLog.setAddTime(newTime);
                        ruleRidePhotoLog.setType(1);
                        ruleRidePhotoLog.setRemark("运维下发拍照");
                        ruleRidePhotoLogService.insert(ruleRidePhotoLog);
                    }

                    if (paramRet != null) {
                        terControlService.respHandle(serNO, paramRet);

                        log.info("paramRet======{}", paramRet);
                        String[] strings = paramRet.split(";");
                        for (String s : strings) {
                            String tmp = s.substring(0, s.contains("=") ? s.indexOf("=") : s.length());
                            tmp = tmp + ";";
                            if (ControlTypeConstant.CONTROL_TYPE_DEVICESTATUSEX.equals(tmp)) {
                                String value = s.substring(s.indexOf("=") + 1);

                                /**指令*/
                                OrderLog orderLog = orderLogService.getSerNO(serNO);

                                log.info("values======{}", value);
                                if (!"fail".equalsIgnoreCase(value)) {
                                    String machineNO = redisService.get(RedisConstant.QUARTZ_HELMET_DS + serNO);
                                    String machineNORide = redisService.get(RedisConstant.QUARTZ_HELMET_DS_RIDELOG + orderLog.getMachineNo());
                                    if (machineNO != null) {
                                        Integer valueState = Integer.valueOf(value);
                                        if (!ObjectUtil.statusParse(3, valueState)) {
                                            log.info("智能头盔锁不在位，添加异常：{}", machineNO);
                                            machineAbnormalService.insert(new MachineAbnormal(null, dataService.getMachineId(machineNO), null,
                                                    machineNO, MachineAbnormalConstant.MACHINE_ABNORMAL__HELMET_LOSE, null, null, null));
                                        }
                                    } else if (machineNORide != null) {

                                        redisService.add(machineNORide, value);
                                    }
                                }
                            }
                        }
                        OrderLog orderLog = new OrderLog();
                        orderLog.setOrderSerNo(serNO);
                        orderLog.setRspDt(newTime);
                        orderLog.setRspRet(1);
                        orderLog.setRspContent(controlRet);
                        orderLogService.update(orderLog);
                    } else {
                        terControlService.respHandle(serNO, controlRet);
                        OrderLog orderLog = new OrderLog();
                        orderLog.setOrderSerNo(serNO);
                        orderLog.setRspDt(newTime);
                        orderLog.setRspRet(Integer.parseInt(controlRet));
                        orderLog.setRspContent(controlRet);
                        orderLogService.update(orderLog);

                        TerControlMsg<TerMsg> terControlMsg = new TerControlMsg<>();
                        String terControl = redisService.get(RedisConstant.terControlMsg + serNO);
                        try {
                            terControlMsg = JSON.parseObject(terControl, new TypeReference<TerControlMsg<TerMsg>>() {
                            });
                        } catch (JSONException e) {
                            redisService.del(RedisConstant.terControlMsg + serNO);
                        }

                        String machineNO = null;
                        Integer machineId = null;
                        Machine machine = null;
                        Park park = null;
                        if (terControlMsg != null && terControlMsg.getData() != null && terControlMsg.getData().getSn() != null) {
                            machineNO = terControlMsg.getData().getSn();
                            machineId = dataService.getMachineId(machineNO);
                            machine = dataService.getMachine(machineId);
                            park = parkService.getByMachineId(machineId);
                        }

                        /**回复成功*/
                        if (ControlTypeConstant.CONTROL_TYPE_SUCC.equals(controlRet)) {
                            if (machineNO != null) {
                                /**静止超时，系统自动中途停车*/
                                String rideId = redisService.get(RedisConstant.MACHINE_PARK + serNO);
                                if (rideId != null && park == null) {
                                    RideLog rideLog = rideLogService.getByOrderNO(rideId);
                                    /** 添加中途停车记录 */
                                    Park newPark = new Park();
                                    newPark.setAccountId(machine.getAccountId());
                                    newPark.setUserId(rideLog.getUserId());
                                    newPark.setMachineId(machine.getMachineId());
                                    newPark.setStartTime(newTime);
                                    newPark.setRemark("静止超时，系统自动中途停车");
                                    parkService.insert(newPark);
                                    log.info("静止超时，系统自动中途停车:{}", machine.getMachineNO());
                                    // 临时停车服务消息推送
                                    Map<String,Object> paramMap = new HashMap<>();
                                    paramMap.put("orderNO",rideLog.getOrderNO());
                                    paramMap.put("secret","36987");
                                    // 调用客户端接口
                                    String url = String.format("%s%s?", UqbikeManagerConfig.clientsite, "/wx/pushNotReturnBikeMsg.do");
                                    log.info("调用地址{}",url);
                                    String res = HttpUtil.post(url, paramMap);
                                    log.info("静止还车调用小程序接口结果{}",res);
                                }

                                /**添加低电缓存*/
                                String redis = redisService.get(RedisConstant.MACHINE_BORROW_SOC_ + machineNO);
                                if (redis != null) {
                                    /**推送客户端,2分钟*/
                                    redisService.add(RedisConstant.MACHINE_BORROW_SOC_CLIENT + machineNO, newTime, 120);
                                    /**运维断电*/
                                    redisService.add(RedisConstant.MACHINE_BORROW_SOC_MAIN + machineNO, newTime);
                                }
                            }

                            /**运维开锁占用*/
                            String machineUnlockMap = redisService.get(RedisConstant.REDIS_machineUnLockMap + serNO);
                            if (machineUnlockMap != null) {
                                MachineOccupy mo = new MachineOccupy();
                                try {
                                    mo = JSONObject.parseObject(machineUnlockMap, MachineOccupy.class);
                                } catch (JSONException e) {
                                    redisService.del(RedisConstant.REDIS_machineUnLockMap + serNO);
                                }

                                log.info("[运维({}){}占用车辆：{}]", mo.getAccountUserId(), mo.getName(), mo.getMachineId());
                                MachineOccupy machineOccupyDB = machineOccupyService.getByMachineId(mo.getMachineId());
                                if (machineOccupyDB == null) {
                                    machineOccupyService.insert(mo);
                                }

                                /**删除*/
                                redisService.del(RedisConstant.REDIS_machineUnLockMap + serNO);

                                /**取消车辆站点绑定*/
                                machineService.parkMachineInside(mo.getMachineId(), null, 0);

                                /**删除临停缓存*/
                                parkService.del(machineId);
                            }

                            /**运维关锁取消占用*/
                            String machineLockMap = redisService.get(RedisConstant.REDIS_machineLockMap + serNO);
                            if (machineLockMap != null) {
                                /**删除数据库记录*/
                                log.info("[运维取消占用车辆：{}]", machineLockMap);

                                machineOccupyService.del(Integer.valueOf(machineLockMap));

                                /**删除内存记录*/
                                redisService.del(RedisConstant.REDIS_machineLockMap + serNO);

                                /**取消车辆站点绑定*/
                                if (machine != null) {

                                    MachineBorrow machineBorrow = machineBorrowService.getByMachineId(machine.getMachineId());
                                    // 借车，并且没有临停记录
                                    if (null != machineBorrow && park == null) {
                                        /**增加临停缓存*/
                                        Park newPpark = new Park();
                                        newPpark.setAccountId(machine.getAccountId());
                                        newPpark.setUserId(machineBorrow.getUserId());
                                        newPpark.setMachineId(machine.getMachineId());
                                        newPpark.setStartTime(nowTime);
                                        newPpark.setRemark("运维网络关锁标记临停");
                                        parkService.insert(newPpark);
                                    }

                                    MachineStatus machineStatus = machineStatusService.getByMachineId(machine.getMachineId());
                                    if (machineStatus != null) {
                                        /**判断是否是禁停区*/
                                        AccountConfig ac = dataService.getAccountConfig(machine.getAccountId());
                                        if (ac != null && ac.getReturnModel() == 1) {
                                        } else {
                                            /** 重新判断站点 */
                                            ParkPoint parkPointNew = parkPointService.checkInParkPointNew(machine.getAccountId(), new Point(machineStatus.getLon(), machineStatus.getLat()), 100, null);
                                            if (parkPointNew != null) {
                                                machineService.put(new ParkMachine(parkPointNew.getParkPointId(), machine.getMachineId(), parkPointNew.getInside()));
                                            } else {
                                                machineService.parkMachineInside(machine.getMachineId(), null, 0);
                                            }
                                        }

                                    }
                                }
                            }
                        }

                        /**上锁运动中，发送断电指令*/
                        if (ControlTypeConstant.CONTROL_TYPE_MOVING.equals(controlRet)) {
                            if (machineNO != null) {
                                if (terControlMsg != null) {
                                    log.info("[" + machineNO + "]上锁失败-车辆运动中");
                                    /**给终端下发指令*/
                                    String cfSerNO = UUID.randomUUID().toString();
                                    terControlService.sendControl(cfSerNO, machineNO, ControlTypeConstant.CONTROL_TYPE_CONTROL, ControlTypeConstant.CONTROL_TYPE_UNSTART, "");
                                    log.info("[" + machineNO + "]车辆运动中-下发 断电指令");
                                }
                            }

                        }

                    }
                    redisService.del(RedisConstant.terControlMsg + serNO);
                    break;
                default:
                    log.warn("未知消息类型={}", msgId);
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public static void main(String[] args) {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("orderNO","202411056064714418");
        paramMap.put("secret","36987");
        // 调用客户端接口
        String res = HttpUtil.post(String.format("%s%s?", "http://clienttestv4.uqbike.cn", "/wx/pushNotReturnBikeMsg.do"), paramMap);
        System.out.println(res);
    }

}
